/*
 *
 *  Copyright (C) 2010 Tal Eisenberg
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package tal.drivechain.gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.font.FontRenderContext;
import java.text.DecimalFormat;
import tal.drivechain.expression.dcExpression;

/**
 *
 * @author eisental
 */
public class NumberDragSlider extends DragSlider {
    private Color color, darker, xor;
    private boolean negative;
    private int columns;
    private DecimalFormat format;
    private dcExpression display;

    public NumberDragSlider(double value, double maxValue, double minValue, double scale, Color color, int columns, boolean negative) {
        super(value, maxValue, minValue, scale);
        setColor(color);
        this.negative = negative;
        setColumns(columns);
    }

    public NumberDragSlider(double value) {
        this(value, 100, 0, 1, Color.ORANGE, 4, false);
    }

    @Override
    public void addNotify() {
        super.addNotify();
        setSize();
    }

    public dcExpression getDisplay() {
        return display;
    }

    public void setColor(Color color) {
        this.color = color;
        this.xor = new Color(color.getRed()^255, color.getGreen()^255, color.getBlue()^255);
        this.darker = color.darker();
        repaint();
    }

    public void setColumns(int columns) {
        this.columns = columns;
        format = new DecimalFormat();
        int maxFraction = Math.round(columns/3);
        int maxDecimal = columns - maxFraction;
        format.setMaximumFractionDigits(maxFraction);
        format.setMaximumIntegerDigits(maxDecimal);
        setSize();
    } public int getColumns() { return columns; }

    public void setDisplay(dcExpression display) {
        this.display = display;
        repaint();
    }

    public void setNegative(boolean negative) {
        this.negative = negative;
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        /* negative:
         *  released: black background, dark border, dark number
         *  hover: black background, color border and number
         *  drag: black background, color border and xor number
         * !negative:
         *  released: color background, dark border, black number
         *  hover: color background, dark border, xor number
         *  drag: black background, dark border, xor number
         */
        super.paintComponent(g);
        if (negative) {
            switch (curState) {
                case RELEASED:
                    paintBackground(Color.BLACK, g); paintBorder(darker, g); paintNumber(darker, g);
                    break;
                case HOVER:
                    paintBackground(Color.BLACK, g); paintBorder(color, g); paintNumber(color, g);
                    break;
                case DRAG:
                    paintBackground(color, g); paintBorder(color, g); paintNumber(xor, g);
                    break;
            }
        } else {
            switch (curState) {
                case RELEASED:
                    paintBackground(color, g); paintNumber(Color.BLACK, g);
                    break;
                case HOVER:
                    paintBackground(color, g); paintNumber(xor, g);
                    break;
                case DRAG:
                    paintBackground(Color.BLACK, g); paintNumber(xor, g);
                    break;
            }
            paintBorder(darker, g);
        }
    }

    private void paintBackground(Color color, Graphics g) {
        g.setColor(color);
        g.fillRect(0, 0, getWidth(), getHeight());
    }

    private void paintBorder(Color color, Graphics g) {
        g.setColor(color);
        g.drawRect(0,0, getWidth()-1, getHeight()-1);
    }

    private void paintNumber(Color color, Graphics g) {
        String sValue;
        if (display!=null) {
            display.setVariable("value", getValue());
            sValue = display.evaluate().toString();
        } else
            sValue = "" + format.format(getValue());
        int x = (getWidth() - g.getFontMetrics().stringWidth(sValue))/2;
        int y = (g.getFontMetrics().getAscent()+getHeight()-2)/2;
        g.setColor(color);
        g.drawString(sValue, x, y);
    }

    @Override
    public void setFont(Font font) {
        super.setFont(font);
        setSize();
    }

    private void setSize() {
        if (getFont()==null) return;
        String string = "0";
        for (int i=0; i<columns-1; i++)
            string += "0";
        Dimension preferred = new Dimension();
        preferred.width = (int) (getFont().getStringBounds(string, new FontRenderContext(null, false, false)).getWidth() + 6);
        preferred.height = (int) (getFont().getStringBounds(string, new FontRenderContext(null, false, false)).getHeight() + 2);
        this.setSize(preferred);
        this.setPreferredSize(preferred);
        this.setMinimumSize(preferred);
        this.setMaximumSize(preferred);
    }
}
